home *** CD-ROM | disk | FTP | other *** search
- /******** OBJECTS.H Copyright 1992 Gregory Colvin *********
- This program may be distributed free with this notice.
- ***********************************************************/
- #ifndef OBJECTS_H
- #define OBJECTS_H
- #include <assert.h>
- #include <stdlib.h>
- #include <string.h>
-
- #ifndef __cplusplus /* Not C++, assume C */
-
- #if !defined(__MSDOS__) || defined(__STDC__)
- #define near /* near pointers are DOS extension */
- #endif
-
- /* Base class for all objects: */
- typedef struct {
- char near *name;
- int initialized;
- void (*destroy)(void);
- int (*isA)(const char *className);
- } ObjectMethods;
- extern ObjectMethods ObjectTable;
- void ObjectInitClass(void);
- typedef struct Object {
- ObjectMethods near *methods;
- } Object;
- void Object_construct(void);
- void Object_destruct(void);
-
- /* Manage "this" pointer stack for methods: */
- extern Object * near *pThis;
- #define MAX_PUSH 512
- #if 1
- #define PREV_THIS() (*(pThis-1))
- #define PUSH_THIS(pObj) (*--pThis = (Object*)(pObj))
- #define GET_THIS(Class) ((Class*)*pThis)
- #define GET_THIS_SAFE(Class) \
- (assert(IS_A(*pThis,Class)),GET_THIS(Class))
- #define POP_THIS() (*pThis++)
- #define POP_THIS_SAFE(Class) \
- (assert(IS_A(*pThis,Class)),(Class*)POP_THIS())
- #else
- #define PREV_THIS() (*(Object**)_DI)
- #define PUSH_THIS(pObj) ((*(Object**)_DI) = pObj)
- #define GET_THIS(Class) (*(Class**)_DI)
- #define GET_THIS_SAFE(Class) \
- (assert(IS_A(GET_THIS(Class),Class)),GET_THIS(Class))
- #define POP_THIS() (*(Object**)_DI)
- #define POP_THIS_SAFE(Class) GET_THIS_SAFE(Class)
- #endif
-
- /* Begin class methods declaration: */
- #define DCL_METHODS(Class,Base,ConstructorArguments) \
- typedef struct Class##DataStruct Class; \
- void Class##_construct ConstructorArguments; \
- void Class##_destruct(void); \
- struct Class##MethodStruct { \
- Base##Methods base;
-
- /* Declare and redeclare methods: */
- #define DCL_METHOD(Name,Arguments,Return) \
- Return (*Name)Arguments
- #define DCL_ABSTRACT(Name,Arguments,Return) \
- Return (*Name)Arguments
- #define REDCL_METHOD(Name,Arguments,Return) \
- void dummy_##Name
-
- /* End class methods or class type declaration: */
- #define END_METHODS };
-
- /* Begin class members declaration: */
- #define DCL_MEMBERS(Class,Base) \
- typedef struct Class##MethodStruct Class##Methods; \
- extern Class##Methods Class##Table; \
- extern void Class##InitClass(void); \
- struct Class##DataStruct { \
- Base base;
-
- #define END_MEMBERS };
-
- /* Begin class type definition: */
- #define DEF_CLASS(Class,Base) \
- Class##Methods Class##Table = { 0, 0 }; \
- int Class##_isA(const char *className) { \
- int yes= !strcmp(#Class,className); \
- if (!yes) \
- yes = ((ObjectMethods*)(&Base##Table))->isA(className); \
- return yes; \
- } \
- void Class##_destroy(void) { \
- Class##_destruct(); \
- ((ObjectMethods*)(&Base##Table))->destroy(); \
- } \
- void Class##InitClass(void) { \
- ObjectMethods *objTable= (ObjectMethods*)&Class##Table; \
- Base##Methods *baseTable= (Base##Methods*)&Class##Table; \
- Base##InitClass(); \
- if (objTable->initialized) \
- return; \
- *baseTable = Base##Table; \
- objTable->name = #Class; \
- REDEF_METHOD(Class,Object,isA); \
- REDEF_METHOD(Class,Object,destroy);
-
- /* Set and reset methods within a class definition: */
- #define DEF_ABSTRACT(Base,Method) \
- (Base##Table.Method = 0)
- #define DEF_METHOD(Base,Method) \
- (Base##Table.Method = Base##_##Method)
- #define REDEF_METHOD(Class,Base,Method) \
- (((Base##Methods *)(&Class##Table))->Method \
- = Class##_##Method)
-
- /* End class type definition: */
- #define END_CLASS }
-
- /* Initialize a class before use: */
- #define USE(Class) Class##InitClass()
-
- /* Begin class method implementation: */
- #define METHOD(Class,Name,Arguments,Return) \
- Return Class##_##Name Arguments { \
- Class *this = POP_THIS_SAFE(Class);
-
- /* End class method implementation: */
- #define END_METHOD }
-
- /* Begin class constructor implementation: */
- #define CONSTRUCTOR(Class,Arguments) \
- void Class##_construct Arguments { \
- Class *this= GET_THIS(Class); \
- ObjectMethods *Methods= \
- (ObjectMethods *)&Class##Table;
-
- /* Must construct Base first in class constructor: */
- #define CONSTRUCT(Base,Arguments) \
- Base##_construct Arguments; \
- ((Object *)this)->methods = Methods; {
-
- /* End class constructor implementation: */
- #define END_CONSTRUCTOR }}
-
- /* Begin class destructor implementation: */
- #define DESTRUCTOR(Class) \
- void Class##_destruct(void) { \
- Class *this = GET_THIS_SAFE(Class); \
- ((Object *)this)->methods = \
- (ObjectMethods *)&Class##Table; {
-
- /* End class destructor implementation: */
- #define END_DESTRUCTOR }}
-
- /* Monomorphic access to a method of a class: */
- #define CALL(pObj,Class,Base,Name,Arguments) \
- ((PUSH_THIS(pObj), \
- (Base##Methods *)(&Class##Table))->Name Arguments \
- )
-
- /* Polymorphic access to a method of a class: */
- #define SEND(pObj,Base,Name,Arguments) \
- (((Base##Methods*) \
- (PUSH_THIS(pObj)->methods))->Name Arguments)
-
- /* Construct a new object on the heap: */
- #define NEW(Class,Arguments) \
- (PUSH_THIS(malloc(sizeof(Class)))), \
- Class##_construct Arguments, \
- POP_THIS_SAFE(Class)))
-
- /* Construct a new object on the stack: */
- #define PUSH(ObjName,Class,Arguments) \
- Class auto_##ObjName; \
- Class *ObjName = (Class*) \
- (PUSH_THIS(&auto_##ObjName), \
- Class##_construct Arguments, \
- POP_THIS_SAFE(Class))
-
- /* Destroy an object on the heap: */
- #define DELETE(pObj) \
- (SEND(pObj,Object,destroy,()), free(POP_THIS())
-
- /* Destroy an object on the stack: */
- #define POP(pObj) SEND(pObj,Object,destroy, ())
-
- /* Test whether object is a member of named class: */
- #define IS_A(pObj,Class) \
- ((((Object *)pObj)->methods)->isA(#Class))
-
- /* Access to the class name of an object: */
- #define CLASS_NAME(pObj) \
- (((ObjectTable*)(((Object *)(pObj))->methods))->name)
-
- #else /* C++ */
-
- /* Base class for all objects: */
- struct Object {
- virtual int isA(const char *className);
- virtual const char *classname();
- };
-
- /* Begin class methods declaration: */
- #define DCL_METHODS(Class,Base,ConstructorArguments) \
- struct Class : Base { \
- Class ConstructorArguments; \
- virtual ~Class(); \
- virtual int isA(const char *className); \
- virtual const char *classname();
-
- /* Declare and redeclare methods: */
- #define DCL_METHOD(Name,Arguments,Return) \
- virtual Return Name Arguments
- #define DCL_ABSTRACT(Name,Arguments,Return) \
- virtual Return Name Arguments=0
- #define REDCL_METHOD(Name,Arguments,Return) \
- virtual Return Name Arguments
-
- /* End class methods declaration: */
- #define END_METHODS
-
- /* Begin class members declaration: */
- #define DCL_MEMBERS(Class,Base)
-
- /* End class type declaration: */
- #define END_MEMBERS };
-
- /* Begin class type definition: */
- #define DEF_CLASS(Class,Base) \
- const char *Class::classname() { \
- return #Class; \
- } \
- int Class::isA(const char *className) { \
- if (strcmp(#Class,className)) \
- return Base::isA(#Class); \
- return 1; \
- } \
-
- /* Set and reset methods within a class definition: */
- #define DEF_ABSTRACT(Base,Method)
- #define DEF_METHOD(Base,Method)
- #define REDEF_METHOD(Class,Base,Method)
-
- /* End class type definition: */
- #define END_CLASS
-
- /* Initialize a class before use: */
- #define USE(Class)
-
- /* Begin class method implementation: */
- #define METHOD(Class,Name,Arguments,Return) \
- Return Class::Name Arguments {
-
- /* End class method implementation: */
- #define END_METHOD }
-
- /* Begin class constructor implementation: */
- #define CONSTRUCTOR(Class,Arguments) Class::Class Arguments:
-
- /* Must construct Base first in class constructor: */
- #define CONSTRUCT(Base,Arguments) Base Arguments {
-
- /* End class constructor implementation: */
- #define END_CONSTRUCTOR }
-
- /* Begin class desstructor implementation: */
- #define DESTRUCTOR(Class) Class::~Class() {
-
- /* End class destructor implementation: */
- #define END_DESTRUCTOR }
-
- /* Monomorphic access to a method of a class: */
- #define CALL(pObj,Class,Base,Name,Arguments) \
- (pObj->Class::Name Arguments)
-
- /* Polymorphic access to a method of a class: */
- #define SEND(pObj,Base,Name,Arguments) \
- (pObj->Name Arguments)
-
- /* Construct a new object on the heap: */
- #define CREATE(Class) new Class
-
- /* Construct a new object on the stack: */
- #define PUSH(ObjName,Class,Arguments) \
- Class auto##ObjName Arguments; \
- Class *ObjName= &auto##ObjName
-
- /* Destroy an object on the heap: */
- #define DELETE(pObj) \
- delete(pObj)
-
- /* Destroy an object on the stack: */
- #define POP(pObj)
-
- /* Test whether object is a member of named class: */
- #define IS_A(pObj,className) \
- SEND(pObj,Object,isA,(className))
-
- /* Access to the class name of an object: */
- #define CLASS_NAME(pObj) (pObj->classname())
-
- #endif /* C vs. C++ */
-
- #endif
-